From: cl349@firebug.cl.cam.ac.uk Date: Thu, 11 May 2006 16:30:50 +0000 (+0100) Subject: Add support to domain builders for loading kernels with physical addresses in the... X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~16047^2~82 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=15efc30a115d80da597e88dabfd8bd4914645b35;p=xen.git Add support to domain builders for loading kernels with physical addresses in the elf paddr and entry fields. Add a new __xen_guest header field to distinguish between kernels with the previous use of the paddr field and the new use. Add a new __xen_guest header field to control the kernel entry point, since the elf header entry field now points to a physical address. This header field is also useful for supporting alternative entry points in kernel images which run both on xen and native. Also add a kernel config option to control whether the resulting kernel should include compatibility code to run on Xen 3.0.2 or whether such code such be left out, resulting in a kernel which will only run on newer Xen versions. Default to having compatibility enabled. Kernels built with the new use of the elf header fields would otherwise not work on Xen versions prior to this changeset. Signed-off-by: Christian Limpach --- diff --git a/buildconfigs/linux-defconfig_xen0_x86_32 b/buildconfigs/linux-defconfig_xen0_x86_32 index 4c040a58ae..defb6d72da 100644 --- a/buildconfigs/linux-defconfig_xen0_x86_32 +++ b/buildconfigs/linux-defconfig_xen0_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-xen0 -# Sat Apr 8 11:34:07 2006 +# Linux kernel version: 2.6.16.13-xen0 +# Thu May 11 17:06:31 2006 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -1309,7 +1309,7 @@ CONFIG_CRYPTO_CRC32C=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030101 +CONFIG_XEN_INTERFACE_VERSION=0x00030202 # # XEN @@ -1330,10 +1330,12 @@ CONFIG_XEN_NETDEV_LOOPBACK=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_BLKDEV_TAP is not set -# CONFIG_XEN_TPMDEV_FRONTEND is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y +CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_LATEST_ONLY is not set +CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_NO_IDLE_HZ=y diff --git a/buildconfigs/linux-defconfig_xen0_x86_64 b/buildconfigs/linux-defconfig_xen0_x86_64 index 763b918e27..dd358f5896 100644 --- a/buildconfigs/linux-defconfig_xen0_x86_64 +++ b/buildconfigs/linux-defconfig_xen0_x86_64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-xen0 -# Thu Apr 13 14:58:29 2006 +# Linux kernel version: 2.6.16.13-xen0 +# Thu May 11 17:17:19 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -1250,7 +1250,7 @@ CONFIG_CRYPTO_CRC32C=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030101 +CONFIG_XEN_INTERFACE_VERSION=0x00030202 # # XEN @@ -1271,10 +1271,12 @@ CONFIG_XEN_NETDEV_LOOPBACK=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_BLKDEV_TAP is not set -# CONFIG_XEN_TPMDEV_FRONTEND is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y +CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_LATEST_ONLY is not set +CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_NO_IDLE_HZ=y diff --git a/buildconfigs/linux-defconfig_xenU_x86_32 b/buildconfigs/linux-defconfig_xenU_x86_32 index 950220c079..b1cba934ef 100644 --- a/buildconfigs/linux-defconfig_xenU_x86_32 +++ b/buildconfigs/linux-defconfig_xenU_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc3-xen0 -# Thu Feb 16 22:53:43 2006 +# Linux kernel version: 2.6.16.13-xenU +# Thu May 11 17:08:12 2006 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -617,11 +617,7 @@ CONFIG_DUMMY_CONSOLE=y # # -# SN Devices -# - -# -# EDAC - error detection and reporting (RAS) +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # # CONFIG_EDAC is not set @@ -852,7 +848,7 @@ CONFIG_CRYPTO_CRC32C=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_NO_IDLE_HZ=y +CONFIG_XEN_INTERFACE_VERSION=0x00030202 # # XEN @@ -862,12 +858,15 @@ CONFIG_XEN_UNPRIVILEGED_GUEST=y # CONFIG_XEN_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_TPMDEV_FRONTEND is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y +CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_LATEST_ONLY is not set +CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y +CONFIG_NO_IDLE_HZ=y # # Library routines @@ -883,4 +882,6 @@ CONFIG_GENERIC_PENDING_IRQ=y CONFIG_X86_SMP=y CONFIG_X86_BIOS_REBOOT=y CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_NO_TSS=y +CONFIG_X86_NO_IDT=y CONFIG_KTIME_SCALAR=y diff --git a/buildconfigs/linux-defconfig_xenU_x86_64 b/buildconfigs/linux-defconfig_xenU_x86_64 index ffa1bff0f4..ce83a618b8 100644 --- a/buildconfigs/linux-defconfig_xenU_x86_64 +++ b/buildconfigs/linux-defconfig_xenU_x86_64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-xenU -# Thu Apr 13 14:59:16 2006 +# Linux kernel version: 2.6.16.13-xenU +# Thu May 11 17:17:57 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -1135,7 +1135,7 @@ CONFIG_CRYPTO_CRC32C=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030101 +CONFIG_XEN_INTERFACE_VERSION=0x00030202 # # XEN @@ -1145,10 +1145,12 @@ CONFIG_XEN_UNPRIVILEGED_GUEST=y # CONFIG_XEN_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_TPMDEV_FRONTEND is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y +CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_LATEST_ONLY is not set +CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_NO_IDLE_HZ=y diff --git a/buildconfigs/linux-defconfig_xen_x86_32 b/buildconfigs/linux-defconfig_xen_x86_32 index 5ef11bc386..1b7440637a 100644 --- a/buildconfigs/linux-defconfig_xen_x86_32 +++ b/buildconfigs/linux-defconfig_xen_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-xen -# Thu Apr 20 17:07:18 2006 +# Linux kernel version: 2.6.16.13-xen +# Thu May 11 17:11:00 2006 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -888,7 +888,7 @@ CONFIG_MTD_NAND_DISKONCHIP=m # CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y -CONFIG_MTD_NAND_NANDSIM=y +CONFIG_MTD_NAND_NANDSIM=m # # OneNAND Flash Device Drivers @@ -3009,7 +3009,7 @@ CONFIG_CRYPTO_TEST=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030101 +CONFIG_XEN_INTERFACE_VERSION=0x00030202 # # XEN @@ -3030,10 +3030,12 @@ CONFIG_XEN_NETDEV_LOOPBACK=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_BLKDEV_TAP is not set -CONFIG_XEN_TPMDEV_FRONTEND=m CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y +CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_LATEST_ONLY is not set +CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_NO_IDLE_HZ=y diff --git a/buildconfigs/linux-defconfig_xen_x86_64 b/buildconfigs/linux-defconfig_xen_x86_64 index a076efff9d..87cc8e69bb 100644 --- a/buildconfigs/linux-defconfig_xen_x86_64 +++ b/buildconfigs/linux-defconfig_xen_x86_64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-xen -# Thu Apr 20 17:05:48 2006 +# Linux kernel version: 2.6.16.13-xen +# Thu May 11 17:18:58 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -840,7 +840,7 @@ CONFIG_MTD_NAND_DISKONCHIP=m # CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y -CONFIG_MTD_NAND_NANDSIM=y +CONFIG_MTD_NAND_NANDSIM=m # # OneNAND Flash Device Drivers @@ -2841,7 +2841,7 @@ CONFIG_CRYPTO_TEST=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030101 +CONFIG_XEN_INTERFACE_VERSION=0x00030202 # # XEN @@ -2863,10 +2863,12 @@ CONFIG_XEN_TPMDEV_BACKEND=m CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_BLKDEV_TAP is not set -CONFIG_XEN_TPMDEV_FRONTEND=m CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y +CONFIG_XEN_COMPAT_030002_AND_LATER=y +# CONFIG_XEN_COMPAT_LATEST_ONLY is not set +CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_NO_IDLE_HZ=y diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S index 23e62c0543..00ec0c2a5e 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S @@ -23,6 +23,8 @@ #define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability #define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id +#define VIRT_ENTRY_OFFSET 0x0 +.org VIRT_ENTRY_OFFSET ENTRY(startup_32) movl %esi,xen_start_info cld @@ -155,6 +157,14 @@ ENTRY(cpu_gdt_table) .ascii ",XEN_VER=xen-3.0" .ascii ",VIRT_BASE=0x" utoa __PAGE_OFFSET +#ifdef CONFIG_XEN_COMPAT_030002 + .ascii ",ELF_PADDR_OFFSET=0x" + utoa __PAGE_OFFSET +#else + .ascii ",ELF_PADDR_OFFSET=0x0" +#endif /* !CONFIG_XEN_COMPAT_030002 */ + .ascii ",VIRT_ENTRY=0x" + utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET) .ascii ",HYPERCALL_PAGE=0x" utoa ((__PHYSICAL_START+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT) .ascii ",FEATURES=writable_page_tables" diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S index 1f3e07bfb0..11ea79f8a6 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S @@ -24,6 +24,8 @@ .text .code64 +#define VIRT_ENTRY_OFFSET 0x0 +.org VIRT_ENTRY_OFFSET .globl startup_64 startup_64: ENTRY(_start) @@ -146,8 +148,18 @@ gdt_end: .section __xen_guest .ascii "GUEST_OS=linux,GUEST_VER=2.6" .ascii ",XEN_VER=xen-3.0" - .ascii ",VIRT_BASE=0x"; utoh __START_KERNEL_map - .ascii ",HYPERCALL_PAGE=0x"; utoh (phys_hypercall_page >> PAGE_SHIFT) + .ascii ",VIRT_BASE=0x" + utoh __START_KERNEL_map +#ifdef CONFIG_XEN_COMPAT_030002 + .ascii ",ELF_PADDR_OFFSET=0x" + utoh __START_KERNEL_map +#else + .ascii ",ELF_PADDR_OFFSET=0x0" +#endif /* !CONFIG_XEN_COMPAT_030002 */ + .ascii ",VIRT_ENTRY=0x" + utoh (__START_KERNEL_map + __PHYSICAL_START + VIRT_ENTRY_OFFSET) + .ascii ",HYPERCALL_PAGE=0x" + utoh (phys_hypercall_page >> PAGE_SHIFT) .ascii ",FEATURES=writable_page_tables" .ascii "|writable_descriptor_tables" .ascii "|auto_translated_physmap" diff --git a/linux-2.6-xen-sparse/drivers/xen/Kconfig b/linux-2.6-xen-sparse/drivers/xen/Kconfig index 45f53ab0cd..34fe912fae 100644 --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig @@ -198,6 +198,22 @@ config XEN_SYSFS help Xen hypervisor attributes will show up under /sys/hypervisor/. +choice + prompt "Xen version compatibility" + default XEN_COMPAT_030002_AND_LATER + + config XEN_COMPAT_030002_AND_LATER + bool "3.0.2 and later" + + config XEN_COMPAT_LATEST_ONLY + bool "no compatibility code" + +endchoice + +config XEN_COMPAT_030002 + bool + default XEN_COMPAT_030002_AND_LATER + endmenu config HAVE_ARCH_ALLOC_SKB diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h index cfdffff258..60f1742118 100644 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h @@ -289,9 +289,10 @@ extern int page_is_ram(unsigned long pagenr); #endif #define __KERNEL_START (__PAGE_OFFSET + __PHYSICAL_START) +#ifdef CONFIG_XEN_COMPAT_030002 #undef LOAD_OFFSET #define LOAD_OFFSET 0 - +#endif /* CONFIG_XEN_COMPAT_030002 */ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h index 73d9282a85..3144836406 100644 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h @@ -260,8 +260,10 @@ static inline pgd_t __pgd(unsigned long x) #define __PAGE_OFFSET 0xffff880000000000 #endif /* !__ASSEMBLY__ */ +#ifdef CONFIG_XEN_COMPAT_030002 #undef LOAD_OFFSET #define LOAD_OFFSET 0 +#endif /* CONFIG_XEN_COMPAT_030002 */ /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) diff --git a/tools/libxc/xc_load_elf.c b/tools/libxc/xc_load_elf.c index a60fd42d2a..610f0a53df 100644 --- a/tools/libxc/xc_load_elf.c +++ b/tools/libxc/xc_load_elf.c @@ -58,7 +58,7 @@ static int parseelfimage(const char *image, Elf_Ehdr *ehdr = (Elf_Ehdr *)image; Elf_Phdr *phdr; Elf_Shdr *shdr; - unsigned long kernstart = ~0UL, kernend=0UL; + unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base; const char *shstrtab; char *guestinfo=NULL, *p; int h; @@ -148,35 +148,47 @@ static int parseelfimage(const char *image, dsi->xen_guest_string = guestinfo; + virt_base = 0; + if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL ) + virt_base = strtoul(p+10, &p, 0); + dsi->elf_paddr_offset = virt_base; + if ( (p = strstr(guestinfo, "ELF_PADDR_OFFSET=")) != NULL ) + dsi->elf_paddr_offset = strtoul(p+17, &p, 0); + for ( h = 0; h < ehdr->e_phnum; h++ ) { phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize)); if ( !is_loadable_phdr(phdr) ) continue; - if ( phdr->p_paddr < kernstart ) - kernstart = phdr->p_paddr; - if ( (phdr->p_paddr + phdr->p_memsz) > kernend ) - kernend = phdr->p_paddr + phdr->p_memsz; + vaddr = phdr->p_paddr - dsi->elf_paddr_offset + virt_base; + if ( vaddr < kernstart ) + kernstart = vaddr; + if ( (vaddr + phdr->p_memsz) > kernend ) + kernend = vaddr + phdr->p_memsz; } + if ( virt_base ) + dsi->v_start = virt_base; + else + dsi->v_start = kernstart; + + dsi->v_kernentry = ehdr->e_entry; + if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL ) + dsi->v_kernentry = strtoul(p+11, &p, 0); + if ( (kernstart > kernend) || - (ehdr->e_entry < kernstart) || - (ehdr->e_entry > kernend) ) + (dsi->v_kernentry < kernstart) || + (dsi->v_kernentry > kernend) ) { ERROR("Malformed ELF image."); return -EINVAL; } - dsi->v_start = kernstart; - if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL ) - dsi->v_start = strtoul(p+10, &p, 0); - if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) dsi->load_symtab = 1; dsi->v_kernstart = kernstart; dsi->v_kernend = kernend; - dsi->v_kernentry = ehdr->e_entry; dsi->v_end = dsi->v_kernend; loadelfsymtab(image, 0, 0, NULL, dsi); @@ -204,7 +216,7 @@ loadelfimage( for ( done = 0; done < phdr->p_filesz; done += chunksz ) { - pa = (phdr->p_paddr + done) - dsi->v_start; + pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset; va = xc_map_foreign_range( xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]); chunksz = phdr->p_filesz - done; @@ -217,7 +229,7 @@ loadelfimage( for ( ; done < phdr->p_memsz; done += chunksz ) { - pa = (phdr->p_paddr + done) - dsi->v_start; + pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset; va = xc_map_foreign_range( xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]); chunksz = phdr->p_memsz - done; diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h index f7e8efac5b..4284e0f79b 100644 --- a/tools/libxc/xg_private.h +++ b/tools/libxc/xg_private.h @@ -136,8 +136,11 @@ struct domain_setup_info unsigned long v_kernend; unsigned long v_kernentry; - unsigned int load_symtab; + unsigned long elf_paddr_offset; + unsigned int pae_kernel; + + unsigned int load_symtab; unsigned long symtab_addr; unsigned long symtab_len; diff --git a/xen/common/elf.c b/xen/common/elf.c index 412acae01a..83155e0e08 100644 --- a/xen/common/elf.c +++ b/xen/common/elf.c @@ -23,7 +23,7 @@ int parseelfimage(struct domain_setup_info *dsi) Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr; Elf_Phdr *phdr; Elf_Shdr *shdr; - unsigned long kernstart = ~0UL, kernend=0UL; + unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base; char *shstrtab, *guestinfo=NULL, *p; char *elfbase = (char *)dsi->image_addr; int h; @@ -81,39 +81,50 @@ int parseelfimage(struct domain_setup_info *dsi) dsi->xen_section_string = guestinfo; - for ( h = 0; h < ehdr->e_phnum; h++ ) + if ( guestinfo == NULL ) + guestinfo = ""; + + virt_base = 0; + if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL ) + virt_base = simple_strtoul(p+10, &p, 0); + dsi->elf_paddr_offset = virt_base; + if ( (p = strstr(guestinfo, "ELF_PADDR_OFFSET=")) != NULL ) + dsi->elf_paddr_offset = simple_strtoul(p+17, &p, 0); + + for ( h = 0; h < ehdr->e_phnum; h++ ) { phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); if ( !is_loadable_phdr(phdr) ) continue; - if ( phdr->p_paddr < kernstart ) - kernstart = phdr->p_paddr; - if ( (phdr->p_paddr + phdr->p_memsz) > kernend ) - kernend = phdr->p_paddr + phdr->p_memsz; + vaddr = phdr->p_paddr - dsi->elf_paddr_offset + virt_base; + if ( vaddr < kernstart ) + kernstart = vaddr; + if ( (vaddr + phdr->p_memsz) > kernend ) + kernend = vaddr + phdr->p_memsz; } + if ( virt_base ) + dsi->v_start = virt_base; + else + dsi->v_start = kernstart; + + dsi->v_kernentry = ehdr->e_entry; + if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL ) + dsi->v_kernentry = simple_strtoul(p+11, &p, 0); + if ( (kernstart > kernend) || - (ehdr->e_entry < kernstart) || - (ehdr->e_entry > kernend) ) + (dsi->v_kernentry < kernstart) || + (dsi->v_kernentry > kernend) ) { printk("Malformed ELF image.\n"); return -EINVAL; } - dsi->v_start = kernstart; - - if ( guestinfo != NULL ) - { - if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL ) - dsi->v_start = simple_strtoul(p+10, &p, 0); - - if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) + if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) dsi->load_symtab = 1; - } dsi->v_kernstart = kernstart; dsi->v_kernend = kernend; - dsi->v_kernentry = ehdr->e_entry; dsi->v_end = dsi->v_kernend; loadelfsymtab(dsi, 0); @@ -126,18 +137,19 @@ int loadelfimage(struct domain_setup_info *dsi) char *elfbase = (char *)dsi->image_addr; Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr; Elf_Phdr *phdr; + unsigned long vaddr; int h; - for ( h = 0; h < ehdr->e_phnum; h++ ) + for ( h = 0; h < ehdr->e_phnum; h++ ) { phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); if ( !is_loadable_phdr(phdr) ) continue; + vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start; if ( phdr->p_filesz != 0 ) - memcpy((char *)phdr->p_paddr, elfbase + phdr->p_offset, - phdr->p_filesz); + memcpy((char *)vaddr, elfbase + phdr->p_offset, phdr->p_filesz); if ( phdr->p_memsz > phdr->p_filesz ) - memset((char *)phdr->p_paddr + phdr->p_filesz, 0, + memset((char *)vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 178697f12e..0c0c31ad75 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -173,6 +173,7 @@ struct domain_setup_info unsigned long v_kernend; unsigned long v_kernentry; /* Initialised by loader: Private. */ + unsigned long elf_paddr_offset; unsigned int load_symtab; unsigned long symtab_addr; unsigned long symtab_len;